import { camelCase, isArray, isObject, transform, snakeCase } from "lodash-es";
import queryString from "query-string";

const deepCamelCaseKeys = <T>(obj: any): T => {
  return transform(obj, (result, value, key) => {
    // 将下划线命名转换为小驼峰命名
    const camelCaseKey = camelCase(key as string);

    // 如果值是对象或数组，递归处理
    if (isObject(value)) {
      // @ts-ignore
      result[camelCaseKey] = deepCamelCaseKeys(value);
    } else if (isArray(value)) {
      // @ts-ignore
      result[camelCaseKey] = value.map((item) => deepCamelCaseKeys(item));
    } else {
      // @ts-ignore
      result[camelCaseKey] = value;
    }
  });
};

const deepSnakeCaseKeys = <T extends Record<string, any>>(obj: T): T => {
  return transform(obj, (result, value, key) => {
    // 将驼峰命名转换为下划线命名
    const snakeCaseKey = snakeCase(key as string);

    // 如果值是对象或数组，递归处理
    if (isObject(value)) {
      // @ts-ignore
      result[snakeCaseKey] = deepSnakeCaseKeys(value);
    } else if (isArray(value)) {
      // @ts-ignore
      result[snakeCaseKey] = value.map((item) => deepSnakeCaseKeys(item));
    } else {
      // @ts-ignore
      result[snakeCaseKey] = value;
    }
  });
};

export const createRequest = (baseUrl: string, commonInit?: RequestInit) => {
  return {
    get: <T>(url: string, query?: Record<string, any>, options?: RequestInit) =>
      fetch(queryString.stringifyUrl({ 
        url: baseUrl + url, 
        query: query ? deepSnakeCaseKeys(query) : undefined 
      }), {
        method: "get",
        ...commonInit,
        ...options,
      }).then(async (res) => deepCamelCaseKeys<T>(await res.json())),
    post: <T>(url: string, query?: Record<string, any>, body?: any) =>
      fetch(queryString.stringifyUrl({ 
        url: baseUrl + url, 
        query: query ? deepSnakeCaseKeys(query) : undefined 
      }), {
        method: "POST",
        body: body ? JSON.stringify(deepSnakeCaseKeys(body)) : undefined,
        ...commonInit,
        headers: {
          'Content-Type': 'application/json',
          ...commonInit?.headers
        }
      }).then(async (res) => deepCamelCaseKeys<T>(await res.json())),
    delete: <T>(url: string, query?: Record<string, any>, body?: any) =>
      fetch(queryString.stringifyUrl({ 
        url: baseUrl + url, 
        query: query ? deepSnakeCaseKeys(query) : undefined 
      }), {
        method: "delete",
        body: body ? JSON.stringify(deepSnakeCaseKeys(body)) : undefined,
        ...commonInit,
        headers: {
          'Content-Type': 'application/json',
          ...commonInit?.headers
        }
      }).then((res) => deepCamelCaseKeys<T>(res.json())),
    postForm: <T>(url: string, formData: FormData) => {

      return fetch(baseUrl + url, {
        method: "post",
        body: formData,
        ...commonInit,
      }).then(async (res) => {
        return deepCamelCaseKeys<T>(await res.json())
      });
    },
  };
};
